package com.yibo.message.service.cmd.checkword;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.yibo.message.Helper.CheckWordBuilder;
import com.yibo.message.Helper.SendEmail;
import com.yibo.message.core.CheckWordType;
import com.yibo.db.message.entity.EmailServerEntity;
import com.yibo.db.message.entity.MessageCheckWord;
import com.yibo.db.message.mapper.MessageCheckWordMapper;
import com.yibo.message.core.EmailMessage;
import com.yibo.message.service.EmailService;
import com.yibo.support.helper.Assert;
import com.yibo.support.helper.ObjectHelper;
import com.yibo.support.helper.TimeHelper;
import com.yibo.support.inter.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.List;
import java.util.Properties;

import static com.yibo.support.constant.MsgConstant.*;

/**
 * 邮箱验证码
 *
 * @author zhanglei
 */
public class SendCheckWordFromEmailCommand implements Command<Integer> {

    private static final Logger LOGGER = LoggerFactory.getLogger(SendCheckWordFromEmailCommand.class);

    private String email;

    private String type;

    public SendCheckWordFromEmailCommand(String email,String type){
        this.email = email;
        this.type = type;
    }

    @Override
    public Integer execute() {
        checkArgs();

        //生成验证码
        String word = CheckWordBuilder.build(0,10,4);
        //保存验证码
        saveCheckWord(word);

        EmailServerEntity emailServerEntity = getBean(EmailService.class).emailService();
        Assert.notEmpty(EMAIL_SERVER_NOT_FOUND,emailServerEntity);
        if(ObjectHelper.isEmpty(emailServerEntity)){
            LOGGER.info("email server entity not found, please set email server data!");
        }

        //发送
//        sendSpring(emailServerEntity,word);
        sendMail(emailServerEntity,word);
        return 1;
    }


    /**
     * spring 方式发送邮件
     */
    private void sendSpring(EmailServerEntity emailServerEntity,String word){
        JavaMailSender sender = javaMailSender(emailServerEntity);
        if(sender != null){
            sendMsg(sender,emailServerEntity.getUserName(),word);
        }
    }


    private  void sendMsg(JavaMailSender sender,String sendUserName,String word){
        SimpleMailMessage mail = new SimpleMailMessage();
        // 接受者
        mail.setTo(this.email);
        // 发送者
        mail.setFrom(sendUserName);
        // 主题
        mail.setSubject("易博注册验证");
        //内容
        mail.setText("尊敬的"+this.email+"用户!"+System.lineSeparator()+System.lineSeparator()+"您本次操作验证码为 "+word);
        new Thread(()->{
            int times = 0;
            //连续执行5次，如果还失败，则跳过。
            while(true) {
                try {
                    if(times < 5) {
                        sender.send(mail);
                    }
                    break;
                }catch (Exception e){
                    //此处拒绝抛出异常
                    times ++;
                }
            }
        }).start();
    }


    private void saveCheckWord(String word){
        MessageCheckWordMapper messageCheckWordMapper = getBean(MessageCheckWordMapper.class);

        //当前邮件
        List<MessageCheckWord> checkWordList = messageCheckWordMapper
                .selectList(new EntityWrapper<MessageCheckWord>().eq("email",this.email)
                .eq("type",CheckWordType.register));

        //判断当前验证码是否过期
        if (!ObjectHelper.isEmpty(checkWordList)) {
            String createTime = checkWordList.get(0).getCreateTime();
            Assert.isTrue(EMAIL_NOT_SEND_MORE,
                    System.currentTimeMillis() - TimeHelper.getTime(createTime) < 60 * 1000);

            //如果过时了，删除
            messageCheckWordMapper.deleteById(checkWordList.get(0).getId());
        }

        //重新创建新的验证码
        MessageCheckWord messageCheckWord = new MessageCheckWord()
                .setId(ObjectHelper.primaryKey())
                .setCheckWord(word)
                .setEmail(this.email)
                .setType(this.type)
                .setCreateTime(TimeHelper.getNow());
        getBean(MessageCheckWordMapper.class).insert(messageCheckWord);
    }

    /**
     * 通过javamail的方式发送邮件
     *
     * @param emailServerEntity   邮件发服务器实体
     * @param word       验证码
     */
    private void sendMail(EmailServerEntity emailServerEntity,String word){
        EmailMessage message = new EmailMessage();
        message.setTitle("易博注册验证");
        message.setMessage("尊敬的" + this.email + "用户!" + System.lineSeparator() + System.lineSeparator() + "您本次操作验证码为 " + word);
        message.setEmail(this.email);
        SendEmail.send(emailServerEntity,message);

    }

    private JavaMailSender  javaMailSender(EmailServerEntity emailServerEntity){
        JavaMailSender javaMailSender = getBean(JavaMailSender.class);
        if(javaMailSender instanceof JavaMailSenderImpl){
            ((JavaMailSenderImpl) javaMailSender).setHost(emailServerEntity.getHost());
            ((JavaMailSenderImpl) javaMailSender).setUsername(emailServerEntity.getUserName());
            ((JavaMailSenderImpl) javaMailSender).setPassword(emailServerEntity.getPassword());
            ((JavaMailSenderImpl) javaMailSender).setPort(emailServerEntity.getPort());
            return javaMailSender;
        }
        return null;
    }



    private  void checkArgs(){
        Assert.hasEmpty(EMAIL_IS_EMPTY,this.email,this.type);
        Assert.isTrue(EMAIL_IS_EMPTY,!CheckWordType.contain(this.type));
    }
}
